﻿//---------------------------------------------------------------------------------
// Copyright 2011 Microsoft Corporation
// Licensed under the Microsoft Public License (MS-PL) (the "License"); 
// You may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.opensource.org/licenses/ms-pl.html
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR 
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 
// INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR 
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
// MERCHANTABLITY OR NON-INFRINGEMENT. 
// See the Microsoft Public License (MS-PL) for the specific language governing 
// permissions and limitations under the License.
//---------------------------------------------------------------------------------

using Microsoft.Telco.Controls;
using Microsoft.Telco.Controls.Messaging.AudioProvider;
using ControlTestApplications.Silverlight.Dashboard.GatewayService;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.ServiceModel;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace ControlTestApplications.Silverlight.Dashboard
{
    public partial class Messaging : Page
    {

        #region Private Fields

        private TimeSpan messageRetrievalSpan = new TimeSpan(0, 0, 20);
        private string errorMessage;
        ObservableCollection<ReceivedMessage> messages;

        private System.Windows.Threading.DispatcherTimer updateMessageTimer;

        #endregion

        #region Constructor

        public Messaging()
        {
            InitializeComponent();
            updateMessageTimer = new System.Windows.Threading.DispatcherTimer();
            updateMessageTimer.Tick += new EventHandler(updateMessageTimer_Tick);
            updateMessageTimer.Interval = messageRetrievalSpan;
            Loaded += (s, e) =>
            {
                messages = new ObservableCollection<ReceivedMessage>();
                smsControl.ReceivedMessages = messages;
                updateMessageTimer.Start();
            };
        }


        #endregion

        #region OverrideMethods

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        #endregion

        #region Events

        void smsControl_SendSMSTriggerEvent(object sender, EventArgs e)
        {
            GatewayServiceClient client = new GatewayServiceClient();
            ObservableCollection<string> coll = new ObservableCollection<string>();
            foreach (var item in smsControl.ToNumbers)
            {
                coll.Add(item);
            }

            switch (smsControl.Mode)
            {
                case SMSControlMode.SMS:
                    client.SendSMSCompleted += client_SendSMSCompleted;
                    client.SendSMSAsync(ServiceProperties.UserId, ServiceProperties.Origin, coll, smsControl.Message);
                    break;

                //case SMSControlMode.MMS:
                //    client.SendMMSCompleted += client_SendMMSCompleted;
                //    MMSDto dto = new MMSDto();
                //    dto.Subject = smsControl.Message;
                //    dto.Files = new ObservableCollection<MMSFileInfoDto>();
                //    foreach (var file in smsControl.Files)
                //    {
                //        dto.Files.Add(new MMSFileInfoDto { FileName = file.Name, Contents = GetBytesFromFile(file) });
                //    }
                //    client.SendMMSAsync(coll, dto);
                //    break;
                //default:
                //    break;
            }

        }

        void client_SendSMSCompleted(object sender, SendSMSCompletedEventArgs e)
        {
            if (!HasError(e))
            {

                // Update status
                var status = e.Result[0];
                if (status != null)
                    smsControl.UpdateStates(true, MessageState.Sending, string.Format("Message {0} sent.", status));

                GatewayServiceClient client = new GatewayServiceClient();
                client.GetSMSStatusCompleted += client_GetSMSStatusCompleted;
                client.GetSMSStatusAsync(ServiceProperties.UserId, e.Result);
            }
            else
            {
                if (!string.IsNullOrEmpty(errorMessage))
                {
                    smsControl.UpdateStates(true, MessageState.SendingFailed, string.Format("Error: {0}", errorMessage));
                }
            }
        }

        void client_GetSMSStatusCompleted(object sender, GetSMSStatusCompletedEventArgs e)
        {
            if (!HasError(e))
            {
                var status = e.Result[0];

                if (status != null)
                    smsControl.UpdateStates(true, MessageState.SentSuccessfully, string.Format("Message {0} Status: {1}", status.MessageId, status.DeliveryStatus));

            }
            else
            {
                if (!string.IsNullOrEmpty(errorMessage))
                {
                    smsControl.UpdateStates(true, MessageState.SendingFailed, string.Format("Error: {0}", errorMessage));
                }
            }
        }

        void updateMessageTimer_Tick(object sender, EventArgs e)
        {
            GetNewMessages();
        }

        private void transcribeMediaContrl_OnStartPlaying(object sender, EventArgs e)
        {
            GatewayServiceClient client = new GatewayServiceClient();
            client.ConvertTextToSpeechCompleted += new EventHandler<ConvertTextToSpeechCompletedEventArgs>(client_ConvertTextToSpeechCompleted);
            client.ConvertTextToSpeechAsync(transcribeMediaContrl.Text);
        }

        void client_ConvertTextToSpeechCompleted(object sender, ConvertTextToSpeechCompletedEventArgs e)
        {
            if (!HasError(e))
            {
                transcribeMediaContrl.Media = new WaveMediaStreamSource(new MemoryStream(e.Result.Content));
                transcribeMediaContrl.Play();
            }
        }

        private void transcribeMediaContrl_OnStopRecording(object sender, EventArgs e)
        {
            GatewayServiceClient client = new GatewayServiceClient();
            client.TranscribeVoiceCompleted += new EventHandler<TranscribeVoiceCompletedEventArgs>(client_TranscribeVoiceCompleted);
            Attachment attchment = new Attachment();
            attchment.Content = transcribeMediaContrl.InputAudioStream.ToArray();
            client.TranscribeVoiceAsync(attchment);
        }

        void client_TranscribeVoiceCompleted(object sender, TranscribeVoiceCompletedEventArgs e)
        {
            if (!HasError(e))
            {
                transcribeMediaContrl.Text = e.Result;
            }
        }

        #region MMS handlers

        //void client_SendMMSCompleted(object sender, SendMMSCompletedEventArgs e)
        //{
        //    if (!HasError(e))
        //    {
        //        //GatewayServiceClient client = new GatewayServiceClient();

        //    }
        //}

        //private void smsControl_FilesSelectedEvent(object sender, EventArgs e)
        //{
        //    var files = smsControl.Files;
        //    if (files.Count == 0)
        //    {
        //        //Developer chooses to overried the default behaviour

        //    }
        //}

        //private byte[] GetBytesFromFile(FileInfo file)
        //{
        //    Stream input = file.OpenRead();
        //    byte[] bytes = new byte[input.Length];
        //    int numBytesToRead = (int)input.Length;
        //    int numBytesRead = 0;
        //    while (numBytesToRead > 0)
        //    {
        //        // Read may return anything from 0 to numBytesToRead.
        //        int n = input.Read(bytes, numBytesRead, numBytesToRead);

        //        // Break when the end of the file is reached.
        //        if (n == 0)
        //            break;

        //        numBytesRead += n;
        //        numBytesToRead -= n;
        //    }
        //    input.Close();
        //    return bytes;
        //} 
        #endregion

        #endregion

        #region Methods

        /// <summary>
        /// Gets new messages from the server.
        /// </summary>
        /// <remarks>
        /// REMOVE THIS METHOD BEFORE DEPLOYING TO PRODUCTION.
        /// 
        /// The retrieval of messages from the server is for demo purposes only.
        /// Messages received by the Telco SDK are not intended for clients, but for the
        /// application as a whole.  Thus, retrieving the messages on behalf of a specific
        /// user makes no sense.
        /// </remarks>
        private void GetNewMessages()
        {
            updateMessageTimer.Stop();
            GatewayServiceClient client = new GatewayServiceClient();
            client.GetSMSMessagesCompleted += (s, e) =>
            {
                if (e.Error == null) // don't call HasError because we don't want the child authentication window to fire each time
                {
                    var newMessages = e.Result;
                    if (newMessages != null)
                    {
                        foreach (var item in newMessages)
                        {
                            messages.Insert(0, new ReceivedMessage
                            {
                                From = item.Origin,
                                Message = item.Message,
                                DateTime = item.Received.ToString()
                            });
                        }

                    }
                }
                else
                {

                    string error = string.Empty;

                    if (e.Error is FaultException<TelcoFault>)
                    {
                        var fault = e.Error as FaultException<TelcoFault>;
                        error = fault.Detail.Message;
                    }
                    else
                    {
                        errorMessage = e.Error.Message;
                    }

                    if (!string.IsNullOrEmpty(error))
                    {
                        smsControl.UpdateStates(true, MessageState.SendingFailed, string.Format("Error: {0}", error));
                    }

                }
                updateMessageTimer.Start();
            };
            client.GetSMSMessagesAsync(ServiceProperties.UserId);
        }

        private bool HasError(AsyncCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                if (e.Error is FaultException<AuthenticationFault>)
                {
                    //Authentication required
                    var fault = e.Error as FaultException<AuthenticationFault>;
                    ChildWindow authWin = new AuthPrompt(fault.Detail.ConsentUrl);
                    authWin.Show();

                    errorMessage = null;
                    return true;
                }
                else if (e.Error is FaultException<TelcoFault>)
                {
                    var fault = e.Error as FaultException<TelcoFault>;
                    errorMessage = fault.Detail.Message;
                }
                else
                {
                    errorMessage = e.Error.Message;
                }
                return true;
            }
            return false;
        }

        #endregion


    }
}
